package com.demo.designmode.template.case2;

import com.demo.designmode.template.case1.ConnectFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 创建一个模板类DaoTemplate
 * @author jiaxXM
 * @date 2024/9/3
 */
@Component
public class DaoTemplate {

    public <T> T query(String sql, Class<T> clazz) throws Exception {
        //通过clazz创建返回值对象
        T t = clazz.newInstance();
        //获取数据库连接
        try (Connection connection = ConnectFactory.getConnection();
             Statement statement = connection.createStatement();
             ResultSet resultSet = statement.executeQuery(sql)
        ) {
            while (resultSet.next()) {
                //获取所有字段
                Field[] fields = clazz.getDeclaredFields();
                //获取所有方法
                Method[] methods = clazz.getDeclaredMethods();
                Map<String, Method> methodNameMap = Arrays.stream(methods)
                        .collect(Collectors.toMap(Method::getName, Function.identity()));
                //把数据库对应的列的值赋值给 泛型T对象的 对应的字段
                for (Field field : fields) {
                    //获取字段名
                    String fieldName = field.getName();
                    //获取set方法
                    Method method = methodNameMap.get("set" + change(fieldName));
                    //获取数据库的列的值
                    Object fieldValue = null;
                    if (field.getType() == String.class) {
                        fieldValue = resultSet.getString(fieldName);
                    }
                    if (field.getType() == Integer.class) {
                        fieldValue = resultSet.getInt(fieldName);
                    }
                    if (field.getType() == Boolean.class) {
                        fieldValue = resultSet.getBoolean(fieldName);
                    }
                    if (field.getType() == Long.class) {
                        fieldValue = resultSet.getLong(fieldName);
                    }
                    if(field.getType() == Double.class){
                        fieldValue = resultSet.getDouble(fieldName);
                    }
                    if(field.getType() == BigDecimal.class){
                        fieldValue = resultSet.getBigDecimal(fieldName);
                    }
                    if (field.getType() == Date.class) {
                        fieldValue = resultSet.getDate(fieldName);
                    }

                    //设置更多的字段类型...
                    //利用反射执行对象的set方法，把数据库的值设置到对象的字段中
                    method.invoke(t, fieldValue);
                }
            }

        }catch (Exception e) {
            e.printStackTrace();
        }

        return t;
    }


    /**
     * 将一个字符串首字母大写，其它字母小写
     *
     * @param str 字符串
     * @return
     */
    private static String change(String str) {
        return str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase();
    }

}
